<?php
require_once ("config.php");
require_once ("Zend/Search/Lucene.php");
require_once ("DBKonexioa.php");
/**
 * Esta clase permitirá hacer busquedas sorbe los favores ofertados por ls usuarios.
 *
 *
 */
class Search {
	private $conn;
	private $indexPath;
	private $index;
	
	/**
	 * These fields won't be included in the search queries
	 */
	private $unindexedFields = array('favId', 'foto', 'puntuacion', 'contador');
	
	public function __construct() {
		try {
			
			$settings = new Config();
			$this->indexPath = $settings->indexPath;
			$this->conn = new DBKonexioa();
			if (!$this->conn->konektatu())
				die("No se ha podido establecer la conexion");
			
		} catch (Exception $e) {
			throw new Exception($e->getMessage());
		}
	}
	/**
	 * Inicializa el index de los favores para poder hacer futuras busquedas sobre el.
	 * @throws Exception
	 */
	private function initialize(){
		try{
			$this->index = Zend_Search_Lucene::open($this->indexPath);
		}catch (Zend_Search_Lucene_Exception $ex){
			throw new Exception($ex->getMessage());
		}
	}
	
	
	
	/**
	 * Creates a new search index file with the current contents of the database's exercise table.
	 * The fields that won't be indexed are specified in the unidexedFields array of the class
	 */
	public function createIndex() {
		//Query for the index
		$sql = "SELECT favor.idFavor as favId, favor.foto, favor.puntuacion, favor.contador, 
		favor.nombre, favor.tipo, favor.localidad, categoria.tipo as nombreCat
		FROM favor, categoria
		WHERE favor.categoria=categoria.idcategoria";
		$result = execSql($sql);
		if($result){
			//Create the index
			$this->index = Zend_Search_Lucene::create($this->indexPath);
	
			//To recognize numerics
			Zend_Search_Lucene_Analysis_Analyzer::setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive());
			
			foreach ($result as $linea){
				
				$this->addDoc($linea,$this->unindexedFields);
				
			}
			
			$this->index->commit();
			$this->index->optimize();
			
		}
	}
	
	
	private function addDoc($documentData, $unindexedFields){
	
		$doc = new Zend_Search_Lucene_Document();
		foreach($documentData as $key => $value){
			
			if(in_array($key,$unindexedFields)){
				$doc->addField(Zend_Search_Lucene_Field::UnIndexed($key, $value, 'utf-8'));
			} else {
				$doc->addField(Zend_Search_Lucene_Field::Text($key, $value, 'utf-8'));
			}
		}
		$this->index->addDocument($doc);
	}
	
	public function reCreateIndex(){
		$this->deleteIndexRecursive($this->indexPath);
		$this->createIndex();
	}
	
	/**
	 * Deletes all the contents of the requested folder, if that folder exists. If the provided path is a file or a symbolic link it is deleted as well.
	 *
	 * @param String $dirname
	 *              Absolute path of the directory whose files are going to be deleted
	 */
	private function deleteIndexRecursive($dirname){
		// Sanity check
		if (!file_exists($dirname)) {
			return false;
		}
	
		// Simple delete for a file
		if (is_file($dirname) || is_link($dirname)) {
			return unlink($dirname);
		}
	
		// Loop through the folder
		$dir = dir($dirname);
		while (false !== $entry = $dir->read()) {
			// Skip pointers
			if ($entry == '.' || $entry == '..') {
				continue;
			}
	
			// Recursive
			$this->deleteIndexRecursive($dirname . DIRECTORY_SEPARATOR . $entry);
		}
	
		// Clean up
		return $dir->close();
		//return rmdir($dirname);
	}
	
	/**
	 * Busca el termino introducido en el index
	 *
	 * @param String $search
	 *              Termino facilitado por el usuario
	 * @return mixed
	 *              Devuelve un array completo de stdClass en el cual se encuentran los resultados 
	 *              de la busqueda ejecutada.
	 * @throws Exception
	 *              Ha habido un error durante la busqueda.
	 */
	public function launchSearch($search) {
		//Return empty array if empty query
		if($search == '')
			return;
	
		//Opens the index
		$this->initialize();
	
		//To recognize numerics
		//Zend_Search_Lucene_Analysis_Analyzer::setDefault(new Zend_Search_Lucene_Analysis_Analyzer_Common_TextNum_CaseInsensitive());
	
		//Remove the limitations of fuzzy and wildcard searches
		Zend_Search_Lucene_Search_Query_Wildcard::setMinPrefixLength(0);
		Zend_Search_Lucene_Search_Query_Fuzzy::setDefaultPrefixLength(0);
	
	
		$finalSearch=$this->fuzzySearch($search);
		$query = Zend_Search_Lucene_Search_QueryParser::parse($finalSearch);
		
	
		//We do the search and send it
		try {
			//$hits can't be returned directly as is, because it's an array of Zend_Search_Lucene_Search_QueryHit
			//which has far more properties than those the client needs to know
			$hits = $this->index->find($query);
			//Ensure the fields are stored with the exact names you want them to be returned otherways this won't work
			$fields = $this->index->getFieldNames();
			$searchResults = array();
			
			foreach($hits as $hit){
				
				$searchResult = new stdClass();
				foreach($fields as $field){
					
					if($field == "favId"){
						$searchResult->id = $hit->$field;
					} else {
						$searchResult->$field = $hit->$field;
					}
				}
				array_push($searchResults,$searchResult);
			}
			
			
			return $searchResults;
		}
		catch (Zend_Search_Lucene_Exception $ex) {
			throw new Exception($ex->getMessage());
		}
	}
	
	
	/**
	 * Removes all search wildcards provided by the user and replaces them with individual term fuzzy search modifiers.
	 * Each requested term is appended with the '~' modifier that tells lucene to do a fuzzy search.
	 *
	 * The Lucene fuzzy search is performed using similarity measurement provided by Levenshtein's distance algorithm.
	 * http://en.wikipedia.org/wiki/Levenshtein_distance
	 *
	 * @param String $search
	 *                      The term (or terms) of the search query
	 * @return String $finalSearch
	 *                      The parsed search query with fuzzy search modifiers applied
	 */
	public function fuzzySearch($search){
		//Decide whether to make the fuzzy search
		$auxSearch=$search;
		$finalSearch=$search;
		$count =0;
		//$array_substitution=array("+","-","_","&","|","!", "(",")", "{","}", "[","]", "^","~", "*","?",":","\\","/","\"", "or","and","not");
		$array_substitution=array("+","-","_","&","|","!", "(",")", "{","}", "[","]", "^","~",":","\\","/","\"", "or","and","not");
	
		$auxSearch=trim(str_replace($array_substitution, ' ', $auxSearch, $count));
		$auxSearch = preg_replace("/\s{2,}/"," ",$auxSearch);
		$auxSearch = preg_replace("/(\w+) (\W)/","$1$2",$auxSearch);
		if ($count==0){
			$finalSearch=str_replace(' ', '~ ', $search);
			$finalSearch=$finalSearch . "~";
		} else {
			$finalSearch = $auxSearch;
		}
		//error_log("replace: " . $auxSearch."\nreplaceCount:".$count."\nfinalSearch: ".$finalSearch."\n",3,"/tmp/search.log");
		return $finalSearch;
	}
	
	function printRes($resultados){
	
		foreach($resultados as $row){
	
			echo "<div class=\"row panel panel-primary\">";
			echo "<div class=\"panel-heading\"><h3>$row->nombre</h3></div>";
	
			echo "<div class=\"panel-body\">";
			echo "<div class=\"col-md-4\">";
			if($row->foto==""){
			$foto="image_not_found.jpg";
			}else{
			$foto=$row->foto;
			}
			//img-thumbnail
			echo "<img class=\"img-thumbnail\" src=\"../images/favImages/$foto\">";
	
			echo "</div>";
			if($row->puntuacion==0){
			$puntuacion="Todavía no puntuado";
			}else{
			$puntuacion=$row->puntuacion/$row->contador;
			$puntuacion=round($puntuacion,1);
			}
			echo "<div class=\"col-md-4\"><br><h2>Puntuación: $puntuacion</h2><br>
			<p> Tipo de favor:". $row->tipo ."</p></div>";
			echo "<div id=\"boton-fav\" class=\"col-md-4\"><br><br><br><br><input  class=\"btn btn-info btn-lg\" type=\"button\" value=\"Ver favor\" onclick=\"showFavour(". $row->id .");\"></div>";
			echo "</div>";
	
			echo "</div>";
	
	
		}
	}
	
	
}




?>